
KMG.SatellitesBackgroundShader = {

	vertexShader: [
		"varying vec2 textureVarying;",

		"void main() {",
		"gl_Position = projectionMatrix * modelViewMatrix *vec4(position.xyz, 1.0);",
		"textureVarying = uv;",
		"}",

	].join( "\n" ),

	fragmentShader: [

		"uniform sampler2D texture;",
		"varying vec2 textureVarying;",

		"void main() {",
		"gl_FragColor = texture2D( texture, textureVarying );",
		"}",

	].join( "\n" )

};

KMG.SatellitesBackgroundObject = function ( context, config ) {

	KMG.BaseObject.call( this );
	var planeMapImage =  this.planeMapImage = new THREE.Object3D();

	var imagePath = "./img/satellites-bkg.jpg";
	var runnerTexture = new THREE.ImageUtils.loadTexture( imagePath );

	var uniforms = {
		texture: { type: "t", value: runnerTexture },
	};

	var shaderMaterial = new THREE.ShaderMaterial( {
		uniforms: 		uniforms,
		vertexShader:   KMG.SatellitesBackgroundShader.vertexShader,
		fragmentShader: KMG.SatellitesBackgroundShader.fragmentShader,
		blending: 		THREE.NormalBlending,
		depthTest: 		false,
		depthWrite: 	false,
		transparent:	true,
		sizeAttenuation: false,
	});
	var geometry = new THREE.PlaneGeometry(1920, 1080);
	var mesh = new THREE.Mesh(geometry, shaderMaterial);
	planeMapImage.add(mesh);

	planeMapImage.update = function() {
	};

	return planeMapImage;

};
KMG.SatellitesBackgroundObject.prototype = Object.create( KMG.BaseObject.prototype );

var _GlobalTime = 0.0;
var _GlobalTimeDelta = 0.00;

KMG.SatelliteObject = function ( context, config, satellites ) {

	KMG.BaseObject.call( this );
	var scope = this;
	this.config = config;
	this.context = context;
	this.context.satelliteVector = [];
	
	var length = satellites.length;
	var starsPlaneContainer = new THREE.Object3D();
	this.context.starPointScene.add(starsPlaneContainer);
	
	var starsTimeLight  =  window.starlighttime.starlight;
	var starTimeVector  = [];
	
	var messageStartTime = 0.0;
	var starSusTime = 0.0;
	var messagesustainedTime = 5000.0;
	
	for(var mw = 0;mw < starsTimeLight.length;mw++)
	{
		var startimes = starsTimeLight[mw];
		var st = startimes.startTime;
		var sust = startimes.sustainedTime;
		if(st > messageStartTime)
		{
			messageStartTime = st;
			starSusTime = sust;
		}
		
		var stars = startimes.stars;
		for(var s = 0;s<stars.length;s++)
		{
			var startime = [,,];
			var name = stars[s];
			startime[0] = name;
			startime[1] = st*1000; //转成毫秒
			startime[2] = sust*1000;//转成毫秒
			starTimeVector.push(startime);
		}
	}
	messageStartTime = 1000*(messageStartTime+starSusTime) ;
	
	addDynamicPointGeometry = function(point, width,height,type,color,alpha)
	{
		var dynamicPoints = [];
		var pathBefore = "assets/earth/stationSource/";
		pathBefore += type;
		
		var paths = [];
		paths.push(pathBefore+"/1.png");
		paths.push(pathBefore+"/2.png");
		paths.push(pathBefore+"/3.png");
		paths.push(pathBefore+"/4.png");
		paths.push(pathBefore+"/5.png");
		paths.push(pathBefore+"/4.png");
		paths.push(pathBefore+"/3.png");
		paths.push(pathBefore+"/2.png");
		paths.push(pathBefore+"/1.png");
	
	   var starsLight = new THREE.Object3D();
	   starsLight.dynamicDeta = 0;
	   starsLight.dynamicIndex = 0;
	   starsLight.dynamicPointObject = [];
	
		for (var i = 0; i < paths.length; i++) {
			var texture = THREE.ImageUtils.loadTexture( paths[i] );
			var material = new THREE.MeshBasicMaterial( {
				color: color,
				map: texture,
				side: THREE.DoubleSide,
				depthTest: true,
				depthWrite: false,
				transparent: true,
				opacity: alpha,
			} );
			var geometry = new THREE.PlaneGeometry( width, height,1);
			var mesh = new THREE.Mesh( geometry, material.clone() );
			mesh.position = point;
			mesh.visible = false;
			
			starsPlaneContainer.add( mesh );
			starsLight.dynamicPointObject.push(mesh);
		}
		
		starsLight.update = function()
		{
			var dynamicPoints = this.dynamicPointObject;
			var dynamicIndex = this.dynamicIndex;
			var dynamicDeta =  this.dynamicDeta;
			
			 var dynamicIndexTemp = dynamicIndex % dynamicPoints.length;
			for (var i = 0; i < dynamicPoints.length; i++) {
				dynamicPoints[i].visible = (i == dynamicIndexTemp);
			}
			if (dynamicDeta % 15 == 0) {
				this.dynamicIndex += 1;
			}
			this.dynamicDeta += 1;
		}
		
		starsLight.reset = function()
		{
			var dynamicPoints = this.dynamicPointObject;
			this.dynamicIndex = 0;
			this.dynamicDeta = 0;
			
			for (var i = 0; i < dynamicPoints.length; i++) {
				dynamicPoints[i].visible = false;
			}
		}
		starsLight.reStart = function()
		{
			var dynamicPoints = this.dynamicPointObject;
			this.dynamicIndex = 0;
			this.dynamicDeta = 0;
			
			for (var i = 0; i < dynamicPoints.length; i++) {
				dynamicPoints[i].visible = false;
			}
		}
		
		return starsLight;
	
	};
	
	function LoadTextrue(path)
	{
		var texture = new THREE.ImageUtils.loadTexture(path);
		texture.needsUpdate = true;
		
		return texture;
	}
	
	addStaticPointGeometry = function(path,point,width,height,color,alpha)
	{
	   var showMessage = new THREE.Object3D();
	  
		var texture = LoadTextrue( path );
		var material = new THREE.MeshBasicMaterial( {
			color: color,
			map: texture,
			side: THREE.DoubleSide,
			depthTest: true,
			depthWrite: false,
			transparent: true,
			opacity: alpha,
		} );
		var geometry = new THREE.PlaneGeometry( width, height,1);
		var mesh = new THREE.Mesh( geometry, material.clone() );
		mesh.position = point;
		showMessage.add( mesh );
		return showMessage;
		
	};
	
	adddynamicMessage = function(point,width,height,timeStart,timeSuspend)
	{
	   
		var material = new THREE.SpriteMaterial( {
			map: null,
			blending: 		THREE.AdditiveBlending,
			depthTest: 	false,
			depthWrite: 	false,
			transparent:	true,
			opacity: 0.0,
		});
		
		var sprite = new THREE.Sprite( material );
		sprite.scale.set( 0, 0, 1 );
		sprite.position = point;
	
		var dynamicMessage = new THREE.Vector3(point.x,point.y, 0);
		
		//调节卫星点亮的时候，罩子的大小，值越大，闪动的罩子越大
		var starLight = addDynamicPointGeometry(dynamicMessage,width,height,8,0x00ff00,1.0); 
		sprite.lightObject = starLight;
		scope.context.starPointScene.add( starLight );
	
		sprite.timeStart = timeStart;
		sprite.timeEnd = timeStart + timeSuspend;
		sprite.animationTime = 0.0;
		sprite.animationSumTime = 10.0;	
		sprite.animationDelta = 0.1;
		
		scope.context.starPointScene.add( sprite );
		scope.context.satelliteVector.push(sprite);

		sprite.update = function(time)
		{
			if(time < this.timeStart)
			{
			}
			else if(time > this.timeStart)
			{
				if(time > this.timeEnd)
				{
					if(this.lightObject != null )
					{
						this.lightObject.reset();
					}
					
					return;
				} 
				else{
					
					if(this.lightObject != null )
					{
						this.lightObject.update();
					}
				
				}
		
			}
		
		};
		
	};
	

	var screenCenter = new THREE.Vector3(100, 100, 1);
	//this.context.showMessage = addStaticPointGeometry("./img/stars/sucess.png",screenCenter,1315,336,0xffffff,1.0);
	
	adddynamicMessage(screenCenter,1315,336,messageStartTime,messagesustainedTime);
	
	for(var k = 0;k<length;k++)
	{
		var satellite = satellites[k];
        var normalTextrue = LoadTextrue(satellite.normalPath);
		
		var material = new THREE.SpriteMaterial( {
			map: normalTextrue,
			blending: 		THREE.AdditiveBlending,
			depthTest: 	false,
			depthWrite: 	false,
			transparent:	true,
		});
		
		var startTimeTemp = -1000.0;
		var startSustimeTemp = 0.0;
		var boolIsDynamic = false;
		
		if(starTimeVector.length != 0)
		{
			for(var st = 0;st< starTimeVector.length;st++)
			{
				if(satellite.name == starTimeVector[st][0])
				{
					startTimeTemp = starTimeVector[st][1];
					startSustimeTemp = starTimeVector[st][2];
					boolIsDynamic = true;
					break;
				}
			}
		}
	
		var sprite = new THREE.Sprite( material );
		sprite.scale.set( 119, 45, 1 );
		sprite.position = new THREE.Vector3(satellite.x + satellite.offsetX, satellite.y + satellite.offsetY, 0);
		
		if(boolIsDynamic == true)
		{
			var dynamicPoint = new THREE.Vector3(satellite.x + satellite.offsetX-30.0, satellite.y + satellite.offsetY, 0);
			var dynamiclight = new THREE.Vector3(satellite.x + satellite.offsetX-30.0, satellite.y + satellite.offsetY, 0);
		
			//调节卫星点亮的时候，罩子的大小，值越大，闪动的罩子越大
			var starLight = addDynamicPointGeometry(dynamicPoint,50,50,5,0x00ff00,1.0); 
			var starLight2 = addDynamicPointGeometry(dynamiclight,200,400,7,0x00ff00,1.0);
			
			sprite.lightObject = starLight;
			sprite.lightObject2 = starLight2;
			
			var lightTexture = LoadTextrue(satellite.lightPath);
			sprite.lightTexture = lightTexture;
			
			this.context.starPointScene.add( starLight );
			this.context.starPointScene.add( starLight2 );
		}
		
		sprite.normalTexture = normalTextrue;
		sprite.timeStart = startTimeTemp;
		sprite.timeEnd = startTimeTemp + startSustimeTemp;
		sprite.animationTime = 0.0;
		sprite.animationSumTime = 10.0;	
		sprite.animationDelta = 0.1;
		
		this.context.starPointScene.add( sprite );
		this.context.satelliteVector.push(sprite);
		
		var index = 0.0;
		
		sprite.update = function(time)
		{
			if(time < this.timeStart)
			{
				this.normalTexture.needsUpdate = true;
				this.material.map = this.normalTexture;
			}
			else if(time > this.timeStart)
			{
				if(time > this.timeEnd)
				{
					if(this.lightObject != null && this.lightObject2!= null )
					{
						this.lightObject.reset();
					    this.lightObject2.reset();
					}

					if(this.lightTexture != null)
					{
					   this.lightTexture.needsUpdate = true;
				        this.material.map = this.lightTexture;
					}
					
					return;
				} 
				else{
					
					if(this.lightObject != null && this.lightObject2!= null )
					{
						this.lightObject.update();
						this.lightObject2.update();
					}
					
					this.normalTexture.needsUpdate = true;
					this.material.map = this.normalTexture;
					
				}
		
			}
		
		};
	
	}

	$(document).keydown(function(event){
	　　　　if(event.keyCode == 82){
		
	　　　　　　_GlobalTimeDelta = 0.0; 
	            _GlobalTime = 0.0;
				
				if(scope.context.satelliteVector)
				{
					for(var k = 0; k< scope.context.satelliteVector.length;k++)
					{
						var sp = scope.context.satelliteVector[k];
						sp.animationTime = 0.0;
						if(sp.lightObject)
						{
							sp.lightObject.reset();
						}
						if(sp.lightObject2)
						{
							sp.lightObject2.reset();
						}
					}
				}

				
	　　　　}
	　　});
	
	

};
KMG.SatelliteObject.prototype = Object.create( KMG.BaseObject.prototype );


KMG.SatellitesRouteObject = function ( context, config, routsContent ) {

	KMG.BaseObject.call( this );
	var scope = this;
	this.config = config;
	this.context = context;
	this.routsContent = routsContent;
	this.routeset = [];
	this.meshs = [];
	this.materials = [];
	

	this.update = function()
	{
		var curTime = this.context.currentTime;
		var second = (curTime / 1000) % 60;
		var index = Math.floor(second / 3);
		if (index < 20) {
			this.removeRoutes();
			this.addRoutes(this.routeset[index]);
		}

		this.updateMaterials();
	};

	this.updateMaterials = function()
	{
		for (var i = 0; i < this.materials.length; i++) {
			var material = this.materials[i];
			var currentTimeUniform = material.uniforms.currentTime;
			if (currentTimeUniform != null) {
				currentTimeUniform.value = this.context.currentTime;
			}
		}
	};

	this.findSatellite = function(name)
	{
		var satellites = this.context.satellites;
		for (var i = 0; i < satellites.length; i++) {
			if (satellites[i].alias == name) {
				return satellites[i];
			}
		}
		return null;
	}

	this.parserRoutes = function()
	{
		this.routeset = this.routsContent["starlines"];
		/*
		for (var i = 0; i < 20; i++) {
			this.routeset[i] = [];
		}

		var minute = this.routsContent.minute;
		var starlines = this.routsContent["starlines"];
		for (var i = 0; i < starlines.length; i++) {
			var starLine = starlines[i];
			var startTime = starLine.times;
			var second = startTime % 60;
			var index = Math.floor(second / 3);
			this.routeset[index].push(starLine);
		}
		*/
	}

	this.computeRoutePoints = function(start, end, timeS, timeE, ratio)
	{
		//ratio = 0.1;

		var point = (new THREE.Vector3()).subVectors(start, end);
		var length = Math.sqrt(Math.pow(point.x,2)+Math.pow(point.y,2)+Math.pow(point.z,2));

		var distanceBetweenCountryCenter = length;

		//	midpoint for the curve
		var mid = new THREE.Vector3((start.x+end.x)*0.5,(start.y+end.y)*0.5,(start.z+end.z)*0.5);

		var midDirection = point.clone();
		midDirection.normalize();
		var temp = midDirection.x;
		midDirection.x = - midDirection.y;
		midDirection.y = temp ;

		midDirection.multiplyScalar( distanceBetweenCountryCenter * ratio );

		mid.x = mid.x + midDirection.x;
		mid.y = mid.y + midDirection.y;
		mid.z = mid.z + midDirection.z;

		//	the normal from start to end
		var normal = (new THREE.Vector3()).subVectors(start,end);
		normal.normalize();

		/*
		 The curve looks like this:

		 midStartAnchor---- mid ----- midEndAnchor
		 /											  \
		 /											   \
		 /												\
		 start/anchor 										 end/anchor

		 splineCurveA							splineCurveB
		 */

		var distanceHalf = distanceBetweenCountryCenter * 0.3

		var startAnchor = start;
		var offsetA = normal.clone().multiplyScalar( distanceHalf );
		var midStartAnchor = new THREE.Vector3(mid.x + offsetA.x,mid.y + offsetA.y,mid.z + offsetA.z);
		var midEndAnchor = new THREE.Vector3(mid.x - offsetA.x,mid.y - offsetA.y,mid.z - offsetA.z);
		var endAnchor = end;

		//	now make a bezier curve out of the above like so in the diagram
		var splineCurveA = new THREE.CubicBezierCurve3( start, startAnchor, midStartAnchor, mid);
		// splineCurveA.updateArcLengths();

		var splineCurveB = new THREE.CubicBezierCurve3( mid, midEndAnchor, endAnchor, end);
		// splineCurveB.updateArcLengths();

		//	how many vertices do we want on this guy? this is for *each* side
		var vertexCountDesired = Math.floor( /*splineCurveA.getLength()*/ distanceBetweenCountryCenter * 0.02 + 6 ) * 2;

		//	collect the vertices
		var points = splineCurveA.getPoints( vertexCountDesired );

		//	remove the very last point since it will be duplicated on the next half of the curve
		points = points.splice(0,points.length-1);

		points = points.concat( splineCurveB.getPoints( vertexCountDesired ) );

		var nodes = [];
		nodes.distance = 0;
		var detaTime = (timeE - timeS) / (points.length - 1);
		for (var i = 0; i < points.length; i++) {
			nodes.push({x:points[i].x, y:points[i].y, t:(timeS + detaTime*i)*1000});
			if (i > 0) {
				nodes.distance += Math.sqrt((points[i].x-points[i-1].x)*(points[i].x-points[i-1].x) + (points[i].y-points[i-1].y)*(points[i].y-points[i-1].y));
			}
		}
		return nodes;
	};

	this.computeRoute = function(line, start, end)
	{
		if (line.nodes == null) {

			//if (line.ratio > 0) {
				var startPoint = new THREE.Vector3(start.x, start.y, 0);
				var endPoint = new THREE.Vector3(end.x, end.y, 0);
				line.nodes = this.computeRoutePoints(startPoint, endPoint, line.times, line.timee, line.ratio*2.0);
			//} else {
			//	line.nodes = [];
			//	line.nodes.push({x:start.x, y:start.y, t:line.times*1000});
			//	line.nodes.push({x:end.x, y:end.y, t:line.timee*1000});
			//	line.nodes.distance = Math.sqrt((start.x-end.x)*(start.x-end.x) + (start.y-end.y)*(start.y-end.y));
			//}
		}
		return line.nodes;
	};

	this.addRoute = function(nodes)
	{

	};

	this.addRoutes = function(starlines)
	{
		var satellites = this.context.satellites;
		var length = starlines.length;
		for (var i = 0; i < length; i++) {
			var starLine = starlines[i];
			var startName = starLine.scids;
			var index = 0;
			if (starLine.useLefts) {
				startName += "-0";
				index ++;
			}
			var endName = starLine.scide;
			if (starLine.useLefte) {
				endName += "-0";
				index ++;
			}
			if(index == 2)
			{
				var sdf =45;
			}
			var startSate = this.findSatellite(startName);
			var endSate = this.findSatellite(endName);
			if (startSate != null && endSate != null) {
				var nodes = this.computeRoute(starLine, startSate, endSate);
				if (nodes != null) {
					this.addRoute(nodes);
				}
			} else {
				var k = 0;
			}
		}
	};

	this.removeRoutes = function()
	{
		for (var i = 0; i < this.meshs.length; i++) {
			var mesh = this.meshs[i];
			if (mesh != null) {
				mesh.geometry.dispose();
				this.remove(mesh);
			}
		}
		this.meshs = [];
		this.materials = [];
	};

	this.parserRoutes();
};
KMG.SatellitesRouteObject.prototype = Object.create( KMG.BaseObject.prototype );


KMG.SatellitesRouteBackObject = function ( context, config, routsContent ) {

	KMG.SatellitesRouteObject.call( this, context, config, routsContent );
	var scope = this;

	this.updateMaterials = function()
	{
		/*
		for (var i = 0; i < this.materials.length; i++) {
			var material = this.materials[i];
			var currentTimeUniform = material.uniforms.currentTime;
			if (currentTimeUniform != null) {
				currentTimeUniform.value += 100;
			}
		}
		*/
	};

	this.addRoute = function(nodes)
	{
		/*
		var points = [], times = [];
		for (var i = 0; i < nodes.length; i++) {
			points.push(new THREE.Vector3(nodes[i].x, nodes[i].y, 0));
			times.push(nodes[i].t);
		}

		var geometryLine = new THREE.Geometry();
		for (var i = 0; i < points.length; i++)
		{
			geometryLine.vertices[i] = new THREE.Vector3( points[i].x, points[i].y, points[i].z );
		}
		//geometryLine.computeLineDistances();

		var material = new THREE.LineBasicMaterial( { color: 0x00ff00, linewidth: 2 } );
		this.materials.push(material);

		var mesh = new THREE.Line( geometryLine, material );
		this.meshs.push(mesh);
		this.add(mesh);
		*/

		/*
		var sumTime = this.context.sumTime;
		var sycleTime = this.context.sycleTime;
		var traceTime = this.context.traceTime;
		var detaDistance = sumTime / nodes.distance;

		var points = [], times = [];
		for (var i = 0; i < nodes.length; i++) {
			points.push(new THREE.Vector3(nodes[i].x, nodes[i].y, 0));
			times.push(nodes[i].t);
		}

		var geometry = new THREE.Geometry();
		for( var i = 0; i < points.length; i ++ ) {
			geometry.vertices.push( points[i] );
		}
		geometry.size = points.size;

		var meshLine = new StreamMeshLine();
		meshLine.setGeometry( geometry, times );

		var resolution = new THREE.Vector2( 1920, 1080);
		var lineMaterial = new THREE.StreamMeshLineMaterial( {
			vertexShader: THREE.CycleStreamMeshLineShader.vertexShader,
			fragmentShader: THREE.CycleStreamMeshLineShader.fragmentShader,
			useMap: false,
			useAlphaMap: false,
			color: new THREE.Color( 0x00ff00 ),
			opacity: 1.0,
			transparent: true,
			resolution: resolution,
			sizeAttenuation: false,
			lineWidth: 6,
			near: context.camera.near,
			far: context.camera.far,
			invertType: 0,
			sycleType: 2,
			sumTime: sumTime,
			sycleTime: 30 * detaDistance,
			traceTime: 20 * detaDistance,
			currentTime: 0.0,
			depthTest: false,
			depthWrite: false,
			blending: THREE.AdditiveBlending,
		});
		this.materials.push(lineMaterial);

		var mesh = new THREE.Mesh( meshLine.geometry, lineMaterial );
		this.meshs.push(mesh);
		this.add(mesh);
		*/

		var sumTime = this.context.sumTime;
		var sycleTime = this.context.sycleTime;
		var traceTime = this.context.traceTime;
		var detaDistance = sumTime / nodes.distance;

		var points = [], times = [];
		for (var i = 0; i < nodes.length; i++) {
			points.push(new THREE.Vector3(nodes[i].x, nodes[i].y, 0));
			times.push(nodes[i].t);
		}

		var geometry = new THREE.Geometry();
		for( var i = 0; i < points.length; i ++ ) {
			geometry.vertices.push( points[i] );
		}
		geometry.size = points.size;

		var meshLine = new MeshLine();
		meshLine.setGeometry( geometry );

		var resolution = new THREE.Vector2( 1920, 1080);
		var lineMaterial = new MeshLineMaterial( {
			vertexShader: MeshLineMaterial.vertexShader,
			fragmentShader: MeshLineMaterial.fragmentShader,
			useMap: false,
			useAlphaMap: false,
			color: new THREE.Color( 0x00ff00 ),
			opacity: 0.2,
			transparent: true,
			resolution: resolution,
			sizeAttenuation: false,
			lineWidth: 6,
			near: context.camera.near,
			far: context.camera.far,
			invertType: 0,
			sycleType: 2,
			sumTime: sumTime,
			sycleTime: 30 * sumTime,
			traceTime: 20 * sumTime,
			currentTime: 0.0,
			depthTest: false,
			depthWrite: false,
			blending: THREE.AdditiveBlending,
		});
		this.materials.push(lineMaterial);

		var mesh = new THREE.Mesh( meshLine.geometry, lineMaterial );
		this.meshs.push(mesh);
		this.add(mesh);
	};
};
KMG.SatellitesRouteBackObject.prototype = Object.create( KMG.BaseObject.prototype );


KMG.SatellitesRouteForeObject = function ( context, config, routsContent ) {

	KMG.SatellitesRouteObject.call( this, context, config, routsContent );
	var scope = this;

	this.addRoute = function(nodes)
	{
		var sumTime = this.context.sumTime;
		var sycleTime = this.context.sycleTime;
		var traceTime = this.context.traceTime;

		var points = [], times = [];
		for (var i = 0; i < nodes.length; i++) {
			points.push(new THREE.Vector3(nodes[i].x, nodes[i].y, 0));
			times.push(nodes[i].t);
		}

		var geometry = new THREE.Geometry();
		for( var i = 0; i < points.length; i ++ ) {
			geometry.vertices.push( points[i] );
		}
		geometry.size = points.size;

		var meshLine = new StreamMeshLine();
		meshLine.setGeometry( geometry, times );

		var resolution = new THREE.Vector2( 1920, 1080);
		var lineMaterial = new THREE.StreamMeshLineMaterial( {
			vertexShader: THREE.CycleStreamMeshLineShader.vertexShader,
			fragmentShader: THREE.CycleStreamMeshLineShader.fragmentShader,
			useMap: false,
			useAlphaMap: false,
			color: new THREE.Color( 0xffffff ),
			opacity: 1,
			transparent: true,
			resolution: resolution,
			sizeAttenuation: false,
			lineWidth: 8,
			near: context.camera.near,
			far: context.camera.far,
			invertType: 0,
			sycleType: 3,
			sumTime: sumTime,
			sycleTime: sycleTime,
			traceTime: traceTime,
			currentTime: 0.0,
			depthTest: false,
			depthWrite: false,
			blending: THREE.AdditiveBlending,
		});
		this.materials.push(lineMaterial);

		var mesh = new THREE.Mesh( meshLine.geometry, lineMaterial );
		this.meshs.push(mesh);
		this.add(mesh);
	};
};
KMG.SatellitesRouteForeObject.prototype = Object.create( KMG.BaseObject.prototype );


KMG.SatellitesEffectsComposer = function(context, renderer) {

	var renderTargetParameters = {
		minFilter: THREE.LinearFilter,
		magFilter: THREE.LinearFilter,
		format: THREE.RGBAFormat,
		stencilBuffer: false
	};

	THREE.EffectComposer.call( this, renderer );
	var scope = this;
	this.context = context;
	this.renderer = renderer;

	var baseRenderPass = new THREE.RenderPass( context.baseScene, context.camera );
	baseRenderPass.clear = true;
	this.addPass( baseRenderPass );

	var mainSave = new THREE.SavePass( new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, renderTargetParameters ) );
	mainSave.clear = false;
	this.addPass( mainSave );
	
	var starPointRenderPass = new THREE.RenderPass( context.starPointScene, context.camera );
	starPointRenderPass.clear = false;
	this.addPass( starPointRenderPass );
	this.addPass(mainSave);
	
	var mainRenderPass = new THREE.RenderPass( context.mainScene, context.camera );
	mainRenderPass.clear = true;
	mainRenderPass.clearAlpha = 0;
	mainRenderPass.clearColor = 0x000000;
	this.addPass( mainRenderPass );

	var effectMainRenderPass = new THREE.RenderPass( context.effectScene, context.camera );
	effectMainRenderPass.clear = false;
	this.addPass( effectMainRenderPass );

	var effectMainFXAA = new THREE.ShaderPass( THREE.FXAAShader );
	this.addPass( effectMainFXAA );

	var effectMainHBlur = new THREE.ShaderPass( THREE.HorizontalBlurShader );
    this.addPass( effectMainHBlur );
	var effectMainVBlur = new THREE.ShaderPass( THREE.VerticalBlurShader );
	this.addPass( effectMainVBlur );

	var effectMainBloom = new THREE.BloomPass( 0.0 );
	this.addPass( effectMainBloom );
	

	var mainBlend = new THREE.ShaderPass( THREE.MixTextureShader, "tDiffuse1" );
	mainBlend.uniforms[ 'opacity' ].value = 1.0;
	mainBlend.uniforms[ 'tDiffuse2' ].value = mainSave.renderTarget;
	this.addPass( mainBlend );

	var effectSave = new THREE.SavePass( new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, renderTargetParameters ) );
	effectSave.clear = false;
	this.addPass( effectSave );

	var effectRenderPass = new THREE.RenderPass( context.effectScene, context.camera );
	effectRenderPass.clear = true;
	effectRenderPass.clearAlpha = 0;
	effectRenderPass.clearColor = 0x000000;
	this.addPass( effectRenderPass );

	var effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
	this.addPass( effectFXAA );

	var effectHBlur = new THREE.ShaderPass( THREE.HorizontalBlurShader );
	this.addPass( effectHBlur );
	var effectVBlur = new THREE.ShaderPass( THREE.VerticalBlurShader );
	this.addPass( effectVBlur );

	var effectBloom = new THREE.BloomPass( 0.0 );
	this.addPass( effectBloom );

	var effectBlend = new THREE.ShaderPass( THREE.MixTextureShader, "tDiffuse1" );
	effectBlend.uniforms[ 'opacity' ].value = 1.0;
	effectBlend.uniforms[ 'tDiffuse2' ].value = effectSave.renderTarget;
	effectBlend.renderToScreen = true;
	this.addPass( effectBlend );

	this.effect = 1;
	this.opacity = 0;
	this.sender = null;
	this.callback = null;
	this.enterEffect = function(callback, sender) {
		this.effect = 1;
		this.opacity = 0;
		this.sender = sender;
		this.callback = callback;
	};
	this.exitEffect = function(callback, sender) {
		this.effect = 0;
		this.opacity = 1;
		this.sender = sender;
		this.callback = callback;
	};

	this.update = function() {
		if (this.effect == 0) {
			this.opacity -= 0.05;
			if (this.opacity < 0) {
				this.opacity = 0;
				if (this.callback != null) {
					this.callback(this.sender);
					this.sender = null;
					this.callback = null;
				}
			}
		} else {
			this.opacity += 0.05;
			if (this.opacity > 1) {
				this.opacity = 1;
				if (this.callback != null) {
					this.callback(this.sender);
					this.sender = null;
					this.callback = null;
				}
			}
		}

		var mainBlurAmount = 0.1;
		effectMainHBlur.uniforms[ 'h' ].value = mainBlurAmount / ( window.innerWidth / 2 );
		effectMainVBlur.uniforms[ 'v' ].value = mainBlurAmount / ( window.innerHeight / 2 );
		effectMainFXAA.uniforms["resolution"].value.x = 1 / window.innerWidth;
		effectMainFXAA.uniforms["resolution"].value.y = 1 / window.innerHeight;
		effectMainBloom.copyUniforms["opacity"].value = 0.0;

		var effectBlurAmount = 0.3;
		effectHBlur.uniforms[ 'h' ].value = effectBlurAmount / ( window.innerWidth / 2 );
		effectVBlur.uniforms[ 'v' ].value = effectBlurAmount / ( window.innerHeight / 2 );
		effectFXAA.uniforms["resolution"].value.x = 1 / window.innerWidth;
		effectFXAA.uniforms["resolution"].value.y = 1 / window.innerHeight;
		effectBloom.copyUniforms["opacity"].value = 3.0;

		mainBlend.uniforms[ 'opacity' ].value = this.opacity;
		mainBlend.uniforms[ 'tDiffuse2' ].value = mainSave.renderTarget;

		effectBlend.uniforms[ 'opacity' ].value = this.opacity;
		effectBlend.uniforms[ 'tDiffuse2' ].value = effectSave.renderTarget;
	};

};
KMG.SatellitesEffectsComposer.prototype = Object.create( THREE.EffectComposer.prototype );


KMG.SatellitesScene = function ( domElement, config ) {

	var scope = this;
	this.config = config;
	this.domElement = ( domElement !== undefined ) ? domElement : document;
	this.visible = true;
	this.visibleRoutes = true;

	this.context = {
		container : null,
		composer : null,
		renderer : null,
		camera : null,
		baseScene : null,
		mainScene : null,
		effectScene : null,
		containerWidth : 0,
		containerHeight : 0,
		satellites : [],
		satellites2 : [],
		stelliteRoutes : null,
		weekNumber : 20181212,
		startDay : "2018-12-12",
		sumTime : 1500,
		sycleTime : 12 * 31 * 24 * 60 * 60 * 1000,
		traceTime : 50, //调节线上的光点的尾巴长短，值越大越长
		currentTime : 0,
		detaTime : 15,
		objects : [],
	};

	this.addSatellite = function (name, alias, x, y, offsetX, offsetY) {
		var normalPath = "img/stars/preview/" + name + ".png";
		var lightPath = "img/stars/lightview/" + name + ".png";

		var satellite = {};
		satellite.name = name;
		satellite.alias = alias;
		satellite.normalPath = normalPath;
		satellite.lightPath = lightPath;
		satellite.normalTexture = null;
		satellite.lightTexture = null;
		satellite.x = x - 960;
		satellite.y = (1080 - y) - 540;
		satellite.offsetX = offsetX;
		satellite.offsetY = offsetY;
		this.context.satellites.push(satellite);
	}
	
	this.addSatelliteToScene = function (name, alias, x, y, offsetX, offsetY) {
		var normalPath = "img/stars/preview/" + name + ".png";
		var lightPath = "img/stars/lightview/" + name + ".png";

		var satellite = {};
		satellite.name = name;
		satellite.alias = alias;
		satellite.normalPath = normalPath;
		satellite.lightPath = lightPath;
		satellite.normalTexture = null;
		satellite.lightTexture = null;
		satellite.x = x - 960;
		satellite.y = (1080 - y) - 540;
		satellite.offsetX = offsetX;
		satellite.offsetY = offsetY;
		this.context.satellites2.push(satellite);
	}
	

	this.initSatellites = function()
	{
		var offsetX = 40.0;
		var offsetY = 0.0;

		this.addSatellite("BD2-M2", "BD2-M2-0", 726, 544, offsetX, offsetY);
		this.addSatellite("BD3-M15", "BD3-M15-0", 670, 598, offsetX, offsetY);
		this.addSatellite("BD2-M3", "BD2-M3-0", 618, 652, offsetX, offsetY);
		this.addSatellite("BD3-M8", "BD3-M8-0", 563, 707, offsetX, offsetY);
		this.addSatellite("BD3-M7", "BD3-M7-0", 507, 762, offsetX, offsetY);
		this.addSatellite("BD3-M10", "BD3-M10-0", 453, 814, offsetX, offsetY);
		this.addSatellite("BD3-M9", "BD3-M9-0", 398, 869, offsetX, offsetY);
		this.addSatellite("BD3-M16", "BD3-M16-0", 344, 921, offsetX, offsetY);

		this.addSatellite("BD3-M2", "BD3-M2", 1049, 526, offsetX, offsetY);
		this.addSatellite("BD3-M1", "BD3-M1", 995, 580, offsetX, offsetY);
		this.addSatellite("BD3-M4", "BD3-M4", 944, 630, offsetX, offsetY);
		this.addSatellite("BD3-M3", "BD3-M3", 889, 684, offsetX, offsetY);
		this.addSatellite("BD2-M6", "BD2-M6", 857, 715, offsetX, offsetY);
		this.addSatellite("BD3-M14", "BD3-M14", 775, 798, offsetX, offsetY);
		this.addSatellite("BD3-M13", "BD3-M13", 668, 905, offsetX, offsetY);

		this.addSatellite("BD3-M12", "BD3-M12", 1361, 519, offsetX, offsetY);
		this.addSatellite("BD3-M5", "BD3-M5", 1308, 571, offsetX, offsetY); 
		this.addSatellite("BD3-M18", "BD3-M18", 1267, 611, offsetX, offsetY);
		this.addSatellite("BD3-M17", "BD3-M17", 1163, 715, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M18", "BD3-M18", 1267, 611, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M17", "BD3-M17", 1163, 715, offsetX, offsetY);
		
		this.addSatellite("BD3-M11", "BD3-M11", 1043, 834, offsetX, offsetY);
		this.addSatellite("BD3-M6", "BD3-M6", 987, 890, offsetX, offsetY);

		this.addSatellite("BD2-M2", "BD2-M2", 1639, 545, offsetX, offsetY);
		this.addSatellite("BD3-M15", "BD3-M15", 1583, 598, offsetX, offsetY);
		this.addSatellite("BD2-M3", "BD2-M3", 1529, 652, offsetX, offsetY);
		this.addSatellite("BD3-M8", "BD3-M8", 1475, 706, offsetX, offsetY);
		this.addSatellite("BD3-M7", "BD3-M7", 1418, 762, offsetX, offsetY);
		this.addSatellite("BD3-M10", "BD3-M10", 1366, 813, offsetX, offsetY);
		this.addSatellite("BD3-M9", "BD3-M9", 1310, 870, offsetX, offsetY);
		this.addSatellite("BD3-M16", "BD3-M16", 1259, 920, offsetX, offsetY); 
		
		
		//第二
		this.addSatelliteToScene("BD3-M15", "BD3-M15-0", 670, 598, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M8", "BD3-M8-0", 563, 707, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M7", "BD3-M7-0", 507, 762, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M10", "BD3-M10-0", 453, 814, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M9", "BD3-M9-0", 398, 869, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M16", "BD3-M16-0", 344, 921, offsetX, offsetY);

		this.addSatelliteToScene("BD3-M2", "BD3-M2", 1049, 526, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M1", "BD3-M1", 995, 580, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M4", "BD3-M4", 944, 630, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M3", "BD3-M3", 889, 684, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M14", "BD3-M14", 775, 798, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M13", "BD3-M13", 668, 905, offsetX, offsetY);

		this.addSatelliteToScene("BD3-M12", "BD3-M12", 1361, 519, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M5", "BD3-M5", 1308, 571, offsetX, offsetY); 
		this.addSatelliteToScene("BD3-M18", "BD3-M18", 1267, 611, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M17", "BD3-M17", 1163, 715, offsetX, offsetY);

		
		this.addSatelliteToScene("BD3-M11", "BD3-M11", 1043, 834, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M6", "BD3-M6", 987, 890, offsetX, offsetY);


		this.addSatelliteToScene("BD3-M15", "BD3-M15", 1583, 598, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M8", "BD3-M8", 1475, 706, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M7", "BD3-M7", 1418, 762, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M10", "BD3-M10", 1366, 813, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M9", "BD3-M9", 1310, 870, offsetX, offsetY);
		this.addSatelliteToScene("BD3-M16", "BD3-M16", 1259, 920, offsetX, offsetY); 
	
	
		
	};

	this.enterScene = function(callback, sender)
	{
		scope.context.composer.enterEffect(callback, sender);
	};

	this.exitScene = function(callback, sender)
	{
		scope.context.composer.exitEffect(callback, sender);
	};

	this.isVisible = function()
	{
		return this.visible;
	};

	this.setVisible = function(visible)
	{
		this.visible = visible;
		this.context.controls.enabled = visible;
	};

	this.isVisibleRoutes = function()
	{
		return this.visibleRoutes;
	};

	this.setVisibleRoutes = function(visible)
	{
		this.visibleRoutes = visible;
		if (this.curMainObject != null) {
			if (visible && !this.curMainObject.added) {
				this.context.mainScene.add(this.curMainObject);
				this.curMainObject.added = true;
			} else if (!visible && this.curMainObject.added) {
				this.context.mainScene.remove(this.curMainObject);
				this.curMainObject.added = false;
			}
		}
		if (this.curEffectObject != null) {
			if (visible && !this.curEffectObject.added) {
				this.context.effectScene.add(this.curEffectObject);
				this.curEffectObject.added = true;
			} else if (!visible && this.curEffectObject.added) {
				this.context.effectScene.remove(this.curEffectObject);
				this.curEffectObject.added = false;
			}
		}
	};

	this.setCurDate = function(date)
	{
		var strings = this.context.startDay.split('-');
		if (strings.length == 3) {
			var startDate = new Date(parseInt(strings[0]), parseInt(strings[1]), parseInt(strings[2]), 0, 0, 0, 0);
			var startMillisecond = Date.parse(startDate);
			var dateMillisecond = Date.parse(date);
			this.context.currentTime = (dateMillisecond - startMillisecond);
		}
	};

	this.getCurDate = function()
	{
		var strings = this.context.startDay.split('-');
		if (strings.length == 3) {
			var startDate = new Date(parseInt(strings[0]), parseInt(strings[1]), parseInt(strings[2]), 0, 0, 0, 0);
			var startMillisecond = Date.parse(startDate);
			var curMillisecond = startMillisecond + this.context.currentTime;
			var date = new Date(curMillisecond);
			return date;
		}
		return null;
	};

	this.addObjectToBaseScene = function(object)
	{
		this.context.objects.push(object);
		this.context.baseScene.add(object);
	};

	this.addObjectToMainScene = function(object)
	{
		var find = false;
		for (var i = 0; i < this.context.objects.length; i++) {
			if (this.context.objects[i] == object) {
				find = true;
				break;
			}
		}
		if (!find) {
			this.context.objects.push(object);
		}
		this.context.mainScene.add(object);
		object.added = true;
	};

	this.removeObjectFromMainScene = function(object)
	{
		for (var i = 0; i < this.context.objects.length; i++) {
			if (this.context.objects[i] == object) {
				this.context.objects.splice(i, 1);
				break;
			}
		}
		this.context.mainScene.remove(object);
		object.added = false;
	};

	this.addObjectToEffectScene = function(object)
	{
		var find = false;
		for (var i = 0; i < this.context.objects.length; i++) {
			if (this.context.objects[i] == object) {
				find = true;
				break;
			}
		}
		if (!find) {
			this.context.objects.push(object);
		}
		this.context.effectScene.add(object);
		object.added = true;
	};

	this.removeObjectFromEffectScene = function(object)
	{
		for (var i = 0; i < this.context.objects.length; i++) {
			if (this.context.objects[i] == object) {
				this.context.objects.splice(i, 1);
				break;
			}
		}
		this.context.effectScene.remove(object);
		object.added = false;
	};

	this.reset = function()
	{

	};

	this.start = function()
	{

	};

	this.stop = function()
	{

	};

	this.onSize = function()
	{
		this.context.containerWidth = window.innerWidth;
		this.context.containerHeight = window.innerHeight;

		this.context.camera.aspect = window.innerWidth / window.innerHeight;
		this.context.camera.updateProjectionMatrix();

		this.context.renderer.setSize( window.innerWidth, window.innerHeight );
		this.context.composer.setSize(window.innerWidth, window.innerHeight);
	};
	
	this.onRender = function()
	{
		if (!this.visible) {
			return;
		}

		scope.context.containerWidth = window.innerWidth;
		scope.context.containerHeight = window.innerHeight;
		scope.context.controls.update();

		this.updateRoutes();
		
		for (var i = 0; i < scope.context.objects.length; i++) {
			scope.context.objects[i].update();
		}
		
		 _GlobalTime += _GlobalTimeDelta;

		if(scope.context.satelliteVector)
		{
			for(var k = 0; k<scope.context.satelliteVector.length; k++)
			{
				scope.context.satelliteVector[k].update(_GlobalTime);
			}
		}

		if (this.curMillSecond > 0) {
			scope.context.renderer.setClearColor( 0x001862, 1.0 );
			scope.context.renderer.clear(true, true, true);
			scope.context.composer.render(0.1);
		}
	};

	this.curMillSecond = -1;
	this.curMinute = -1;
	this.curMainObject = null;
	this.curEffectObject = null;
	this.getRoutesContent = function(url)
	{
		var routesContent = null;
		if (url != null) {
			var xhrRouts = new XMLHttpRequest();
			xhrRouts.timeout = 0;
			xhrRouts.withCredentials = false;
			xhrRouts.responseType = "";
			xhrRouts.onload = function() {
				routesContent = JSON.parse(this.response);
			}
			xhrRouts.open("GET", url, false);
			xhrRouts.send(null);
		}
		return routesContent;
	}
	this.updateRoutes = function()
	{
		var curTime = this.context.currentTime;
		var curMinute = Math.floor(curTime / 60000);
		var curWeek = scope.context.weekNumber + Math.floor(curTime / (7 * 24 * 60 * 60 * 1000)); // 一天毫秒数

		if (this.curMinute != curMinute) {
			var url = "data/" + curWeek.toString() + "/" + curMinute.toString() + ".json";
			var routesContent = this.getRoutesContent(url);
			if (routesContent != null) {
				routesContent.minute = curMinute;

				if (this.curMainObject != null && this.curEffectObject != null) {
					this.removeObjectFromMainScene(this.curMainObject);
					this.removeObjectFromEffectScene(this.curEffectObject);
				}

				this.curMinute = curMinute;
				this.curMainObject = new KMG.SatellitesRouteBackObject(this.context, this.config, routesContent);
				this.curEffectObject = new KMG.SatellitesRouteForeObject(this.context, this.config, routesContent);

				this.addObjectToMainScene(this.curMainObject);
				this.addObjectToEffectScene(this.curEffectObject);
			}
		}
		this.setVisibleRoutes(this.visibleRoutes);

		var detaTime = 0;
		if (this.curMillSecond == -1) {
			this.curMillSecond = new Date().getTime();
		} else {
			var curMillSecond = new Date().getTime();
			detaTime = curMillSecond - this.curMillSecond;
			this.curMillSecond = curMillSecond;
		}
		this.context.currentTime += (detaTime * 0.5);
		//在开始的时候同步时间
		_GlobalTimeDelta = detaTime * 0.5;
	};

	this.context.container = this.domElement;
	this.context.renderer = this.config.renderer;

	var cameraZ = 1300;
	this.context.camera = new THREE.PerspectiveCamera( this.config.camera.fieldOfView, window.innerWidth / window.innerHeight, this.config.camera.near, this.config.camera.far );
	this.context.camera.position.z = cameraZ;
	var baseScene = new THREE.Scene();
	var baseAmbientLight = new THREE.AmbientLight( 0x888888 );
	baseScene.add( baseAmbientLight );
	var baseDirectional = new THREE.DirectionalLight( 0xFFFFFF, 2.0);
	baseDirectional.position.set( -1000000, -1000000, 1000000 );
	baseScene.add( baseDirectional );
	baseScene.updateMatrix();
	scope.context.baseScene = baseScene;

	var mainScene = new THREE.Scene();
	var mainAmbientLight = new THREE.AmbientLight( 0x888888 );
	mainScene.add( mainAmbientLight );
	var mainDirectional = new THREE.DirectionalLight( 0xFFFFFF, 2.0);
	mainDirectional.position.set( -1000000, -1000000, 1000000 );
	mainScene.add( mainDirectional );
	mainScene.updateMatrix();
	scope.context.mainScene = mainScene;

	
	var starPointScene = new THREE.Scene();
	var mainLineAmbientLight = new THREE.AmbientLight( 0x888888 );
	starPointScene.add( mainLineAmbientLight );
	var mainLineDirectional = new THREE.DirectionalLight( 0xFFFFFF, 2.0);
	mainLineDirectional.position.set( -1000000, -1000000, 1000000 );
	starPointScene.add( mainLineDirectional );
	starPointScene.updateMatrix();
	scope.context.starPointScene = starPointScene;
	
	
	var effectScene = new THREE.Scene();
	var effectAmbientLight = new THREE.AmbientLight( 0x888888 );
	effectScene.add( effectAmbientLight );
	var effectDirectional = new THREE.DirectionalLight( 0xFFFFFF, 2.0);
	effectDirectional.position.set( -1000000, -1000000, 1000000 );
	effectScene.add( effectDirectional );
	effectScene.updateMatrix();
	this.context.effectScene = effectScene;

	this.addObjectToBaseScene(new KMG.SatellitesBackgroundObject(this.context, this.config));

	this.initSatellites();
	
	KMG.SatelliteObject(this.context, this.config, this.context.satellites2);
	
	this.context.composer = new KMG.SatellitesEffectsComposer(this.context, this.context.renderer);
	this.context.objects.push(this.context.composer);

    this.context.controls = new THREE.OrbitControls(this.context.camera,this.context.renderer.domElement );
    this.context.controls.update(true);
};